package com.zlyx.easy.core.utils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.zlyx.easy.core.annotations.Desc;
import com.zlyx.easy.core.utils.ClassUtils;
import com.zlyx.easy.core.utils.MapClass;

/**
 * @Auth 赵光
 * @Describle
 * @2019年8月17日
 */
public class FieldUtils {

	@Desc("以Map形式存储类的属性")
	private static ConcurrentMap<Class<?>, MapClass> classes = new ConcurrentHashMap<Class<?>, MapClass>();

	@Desc("存储类的实例对象")
	private static ConcurrentMap<Class<?>, Object> objects = new ConcurrentHashMap<Class<?>, Object>();

	public static <T> T newInstance(Class<T> tCls, Map<String, ?> params) {
		if (params == null) {
			return null;
		}
		MapClass mapClass = getMapClass(tCls);
		T t = ClassUtils.newInstance(tCls);
		Field field = null;
		Class<?> fieldType = null;
		Object value = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (String fieldName : params.keySet()) {
				if (mapClass.haveField(fieldName)) {
					field = mapClass.getField(fieldName);
					fieldType = field.getType();
					field.setAccessible(true);
					value = params.get(fieldName);
					if (fieldType == Integer.class && value.getClass() != Integer.class) {
						value = Integer.parseInt((String) value);
					} else if (fieldType == Long.class && value.getClass() != Long.class) {
						value = Long.parseLong((String) value);
					} else if (fieldType == Date.class && value.getClass() != Date.class) {
						if (((String) value).trim().length() == 10) {
							value = (String) value + " 00:00:00";
						}
						value = sdf.parse((String) value);
					}
					field.set(t, value);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return t;
	}

	public static List<Field> getClassFields(Class<?> tClass) {
		return getMapClass(tClass).getFields();
	}

	public static MapClass getMapClass(Class<?> tClass) {
		if (!classes.containsKey(tClass)) {
			registryMapClass(tClass);
		}
		return classes.get(tClass);
	}

	public static void registryMapClass(Class<?> tClass) {
		List<Field> fields = getAllFields(tClass);
		MapClass mapClass = new MapClass();
		try {
			for (Field field : fields) {
				mapClass.addField(field);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		classes.put(tClass, mapClass);
	}

	public static List<Field> getAllFields(Class<?> tClass) {
		return new ArrayList<Field>(Arrays.asList(tClass.getDeclaredFields()));
	}
}
